package com.zxy;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.LinkedList;
import java.util.Random;

public class SnakeGame {
    private LinkedList<Point> snakeBody;
    private Point food;
    private int width;
    private int height;
    private int blockSize;
    private Direction direction;
    private boolean gameOver;

    public enum Direction {
        UP, DOWN, LEFT, RIGHT
    }

    public SnakeGame(int width, int height, int blockSize) {
        this.width = width;
        this.height = height;
        this.blockSize = blockSize;
        snakeBody = new LinkedList<>();
        direction = Direction.RIGHT;
        gameOver = false;
        initialize();
    }

    private void initialize() {
        snakeBody.add(new Point(5, 5));
        snakeBody.add(new Point(4, 5));
        snakeBody.add(new Point(3, 5));
        generateFood();
    }

    private void generateFood() {
        Random random = new Random();
        int x = random.nextInt(width / blockSize) * blockSize;
        int y = random.nextInt(height / blockSize) * blockSize;
        food = new Point(x, y);
    }

    public void move() {
        Point head = new Point(snakeBody.getFirst());
        switch (direction) {
            case UP:
                head.y -= blockSize;
                break;
            case DOWN:
                head.y += blockSize;
                break;
            case LEFT:
                head.x -= blockSize;
                break;
            case RIGHT:
                head.x += blockSize;
                break;
        }

        if (head.x < 0 || head.x >= width || head.y < 0 || head.y >= height) {
            gameOver = true;
            return;
        }

        for (Point p : snakeBody) {
            if (p.equals(head)) {
                gameOver = true;
                return;
            }
        }

        if (head.equals(food)) {
            snakeBody.addFirst(head);
            generateFood();
        } else {
            snakeBody.addFirst(head);
            snakeBody.removeLast();
        }
    }

    public void changeDirection(Direction newDirection) {
        if (newDirection == null) return;
        if ((direction == Direction.UP && newDirection == Direction.DOWN) ||
                (direction == Direction.DOWN && newDirection == Direction.UP) ||
                (direction == Direction.LEFT && newDirection == Direction.RIGHT) ||
                (direction == Direction.RIGHT && newDirection == Direction.LEFT)) {
            return;
        }
        direction = newDirection;
    }

    public boolean isGameOver() {
        return gameOver;
    }

    public void draw(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);

        g.setColor(Color.RED);
        g.fillOval(food.x, food.y, blockSize, blockSize);

        g.setColor(Color.GREEN);
        for (Point p : snakeBody) {
            g.fillRect(p.x, p.y, blockSize, blockSize);
        }
    }
}